# -*- encoding: utf-8 -*-
"""
@File    :   Reip_Windows.py
@Time    :   2023-03-31 18:48
@Author  :   坐公交也用券
@Version :   1.0
@Contact :   liumou.site@qq.com
@Homepage : https://liumou.site
@Desc    :   当前文件作用
"""
import os
import subprocess
import sys
import time
from argparse import ArgumentParser

import wmi
from loguru import logger

from model.IP import EthInfo


class ReIp:
	def __init__(self, a, b, sub, gw, mask, eth, wlan, ds: list):
		"""

		:param a: 需要遍历的IP起始地址
		:param b: 需要遍历的IP结束地址
		:param sub: 设置子网(10.1.1)
		:param gw: 设置网关(10.1.1.1)
		:param mask: 设置掩码(255.255.255.0)
		:param eth: 设置网卡名称
		:param wlan: 是否设置无线网卡
		:param ds: 设置DNS列表
		# :param pac: 设置网络包数量
		"""
		# self.pac = pac
		self.ds = ds
		self.wlan = wlan
		self.eth = eth
		self.mask = mask
		self.gw = gw
		self.sub = sub
		self.b = b
		self.a = a
		self.wireless_adapter = None
		self.ip = None

	def getEth(self):
		"""
		获取网卡实例
		:return:
		"""
		# 创建WMI对象
		wmi_obj = wmi.WMI()
		# 获取无线网卡实例
		self.wireless_adapter = None
		get = wmi_obj.Win32_NetworkAdapterConfiguration(IPEnabled=True)
		if len(get) == 0:
			logger.error("无法获取已启用的有线网卡设备")
			sys.exit(3)
		if len(get) == 1:
			logger.info("找到一个有线网卡设备,将直接使用")
			self.wireless_adapter = get[0]
			return
		logger.info("存在多个有线网卡设备,请选择一个进行配置")
		useDic = []
		for adapter in get:
			print(f"{adapter.Index} : {adapter.Description}")
			useDic.append(adapter.Index)
		use = input("请输入网卡ID值\n")
		if use in useDic:
			logger.info("网卡选择正确")
		else:
			logger.warning("网卡选择错误,没有这个ID值")
			sys.exit(3)
		for adapter in get:
			if adapter.Index == use:
				self.wireless_adapter = adapter
				break
		logger.error("有线网卡信息获取失败")
		sys.exit(2)

	def getEthWlan(self):
		"""
		获取网卡实例
		:return:
		"""
		# 创建WMI对象
		wmi_obj = wmi.WMI()
		# 获取无线网卡实例
		self.wireless_adapter = None
		for adapter in wmi_obj.Win32_NetworkAdapter():
			if adapter.NetConnectionID == self.eth:
				self.wireless_adapter = adapter
				break
		logger.error("无线网卡信息获取失败")
		sys.exit(2)

	def setIp(self, ip):
		"""
		设置IP
		:return:
		"""
		logger.debug(f"正在配置IP: {ip}")
		# 修改IP地址和子网掩码
		if self.wireless_adapter:
			self.wireless_adapter.EnableStatic(IPAddress=[ip], SubnetMask=[self.mask])
			# 设置网关地址
			self.wireless_adapter.SetGateways(DefaultIPGateway=[self.gw])
			# 刷新DNS缓存
			cmd = "ipconfig /flushdns"
			returned_value = os.system(cmd)
			return returned_value == 0
		return False

	def pingTest(self):
		"""
		测试网络是否可用/丢包
		:return: 布尔值
		"""
		run = subprocess.getstatusoutput(f"ping {self.gw}")
		if run[0] == 0:
			logger.info("网络连接成功")
			info = run[1]
			print(info)
			r = str(info).split("\n")
			info = r[8]
			r = str(info).split("=")
			info = r[-1]
			r = str(info).split("%")
			info = r[0]
			r = str(info).split("(")
			res = r[-1]
			if int(res) == 0:
				return True
			logger.warning(f"丢包率: {res}%")
		logger.warning("网络连接失败")
		return False

	# response = ping(self.gw, timeout=2, count=3)  # ping 网关，设置超时时间为2秒，发送3个数据包
	# pack = response.stats_packets_lost
	# if pack == 2:
	# 	logger.warning(f"网关连接失败/出现丢包,丢包数量(总发包3): {pack}")
	# 	return False
	# return True
	# print(response)

	def setDns(self):
		"""
		设置DNS地址
		:return:
		"""
		try:
			self.wireless_adapter.SetDNSServerSearchOrder(self.ds)
			logger.info("DNS设置成功")
		except Exception as e:
			logger.warning("DNS设置失败: %s " % str(e))
			return False

	def start(self):
		if self.wlan:
			self.getEthWlan()
		else:
			self.getEth()
		for i in range(self.a, self.b):
			self.ip = self.sub + "." + str(i)
			logger.debug(f"当前生成IP: {self.ip}")
			if self.setIp(ip=self.ip):
				logger.info("正在等待三秒后测试网关连接")
				time.sleep(3)
				if self.pingTest():
					self.setDns()
					logger.info("配置结束,程序终止...")
					sys.exit(0)
				else:
					logger.warning("当前IP设置异常,正在切换...")


if __name__ == "__main__":
	arg = ArgumentParser(description='当前脚本版本: 1.0', prog="WindowsIP切换")
	arg.add_argument('-a', type=int, default=2, help='设置起始IP值, 默认: 2', required=False)
	arg.add_argument('-b', type=int, default=254, help='设置结束IP值，默认：254', required=False)
	# arg.add_argument('-p', type=int, default=254, help='设置网络检测包发送数量，默认：3', required=False)
	arg.add_argument('-sub', type=str, default="10.1.17", help='设置IP段，默认: 10.1.17', required=False)
	arg.add_argument('-gw', type=str, default="10.1.17.1", help='设置网关，默认: 10.1.17.1', required=False)
	arg.add_argument('-m', type=str, default="255.255.255.0", help='设置子网掩码，默认: 255.255.255.0', required=False)
	arg.add_argument('-d1', type=str, default="180.76.76.76", help='设置首选DNS，默认: 180.76.76.76', required=False)
	arg.add_argument('-d2', type=str, default="119.29.29.29", help='设置备用DNS，默认: 119.29.29.29', required=False)
	helpStr = '设置网卡名称,有线默认: 本地连接，无线默认: WLAN'
	arg.add_argument('-e', type=str, default="本地连接", help=helpStr, required=False)
	arg.add_argument('-w', action="store_true", help='启用无线网卡模式,默认使用有线网卡')
	args = arg.parse_args()
	argA = args.a
	argB = args.b
	# argP = args.p
	argSub = args.sub
	argGw = args.gw
	argMask = args.m
	argEth = args.e
	argWlan = args.w
	argD1 = args.d1
	argD2 = args.d2
	ps = str(argSub).split(".")
	if len(ps) != 3:
		logger.error("子网格式设置错误,标准格式: 10.1.1")
		sys.exit(3)
	dns = [argD1, argD2]
	if argWlan and argEth == "本地连接":
		argEth = "WLAN"
	r = ReIp(a=argA, b=argB, sub=argSub, gw=argGw, mask=argMask, eth=argEth, wlan=argWlan, ds=dns)
	r.start()
